﻿/**
 * Stardust Particle Engine
 * 
 * Homepage
 * 	http://code.google.com/p/stardust-particle-engine/
 * 
 * PDF Manual
 * 	http://stardust-particle-engine.googlecode.com/svn/trunk/manual/Stardust%20Particle%20Engine%20Manual.pdf
 */

package {
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.filters.BlurFilter;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.utils.getTimer;
	import flash.utils.Timer;
	import idv.cjcat.stardust.common.clocks.ImpulseClock;
	import idv.cjcat.stardust.twoD.renderers.PixelRenderer;
	
	[SWF(backgroundColor="#000000", frameRate=60)]
	
	public class Main extends Sprite {
		
		private const PARTICLE_COUNT:int = 600;
		
		private var emitter:PixelEmitter;
		private var noiseBMPD:BitmapData;
		private var canvasBMP:Bitmap;
		private var kirakiraBMP:Bitmap;
		
		public function Main():void {
			
			//bitmap canvas
			//------------------------------------------------------------------------------------------------
				
				canvasBMP = new Bitmap(new BitmapData(465, 465, true, 0));
				kirakiraBMP = new Bitmap(new BitmapData(117, 117, true, 0));
				kirakiraBMP.scaleX = kirakiraBMP.scaleY = 4;
				kirakiraBMP.smoothing = true;
				addChild(canvasBMP);
				addChild(kirakiraBMP);
				
			//------------------------------------------------------------------------------------------------
			
			
			//noise gravity field
			//------------------------------------------------------------------------------------------------
				
				noiseBMPD = new BitmapData(233, 233, false, 0);
				var timer:Timer = new Timer(1000);
				timer.addEventListener(TimerEvent.TIMER, tick);
				timer.start();
				
			//------------------------------------------------------------------------------------------------
			
			
			//Stardust
			//------------------------------------------------------------------------------------------------
				
				var clock:ImpulseClock = new ImpulseClock(PARTICLE_COUNT);
				emitter = new PixelEmitter(clock);
				var renderer:PixelRenderer = new PixelRenderer(canvasBMP.bitmapData);
				renderer.addEmitter(emitter);
				
				//injects particles into the emitter
				clock.impulse();
				
			//------------------------------------------------------------------------------------------------
			
			addEventListener(Event.ENTER_FRAME, mainLoop);
			tick();
		}
		
		private function tick(e:Event = null):void {
			//change noise seed for the noise gravity field
			noiseBMPD.perlinNoise(150, 150, 1, getTimer(), true, true);
			emitter.field.update(noiseBMPD);
		}
		
		private var matrix:Matrix = new Matrix(0.25, 0, 0, 0.25);
		private function mainLoop(e:Event):void {
			kirakiraBMP.bitmapData.fillRect(kirakiraBMP.bitmapData.rect, 0);
			kirakiraBMP.bitmapData.draw(canvasBMP.bitmapData, matrix);
			
			canvasBMP.bitmapData.fillRect(canvasBMP.bitmapData.rect, 0);
			emitter.step();
		}
	}
}

//------------------------------------------------------------------------------------------------

import flash.display.Shape;
import idv.cjcat.stardust.common.clocks.Clock;
import idv.cjcat.stardust.common.initializers.Color;
import idv.cjcat.stardust.common.initializers.Mass;
import idv.cjcat.stardust.common.math.UniformRandom;
import idv.cjcat.stardust.twoD.actions.Deflect;
import idv.cjcat.stardust.twoD.actions.Gravity;
import idv.cjcat.stardust.twoD.actions.Move;
import idv.cjcat.stardust.twoD.actions.SpeedLimit;
import idv.cjcat.stardust.twoD.deflectors.WrappingBox;
import idv.cjcat.stardust.twoD.emitters.Emitter2D;
import idv.cjcat.stardust.twoD.fields.BitmapField;
import idv.cjcat.stardust.twoD.initializers.Position;
import idv.cjcat.stardust.twoD.zones.RectZone;

//------------------------------------------------------------------------------------------------

class PixelEmitter extends Emitter2D {
	
	public var field:BitmapField;
	
	public function PixelEmitter(clock:Clock) {
		super(clock);
		
		//initializers
		addInitializer(new Color(0x00CCFF));
		addInitializer(new Mass(new UniformRandom(3, 1)));
		addInitializer(new Position(new RectZone(0, 0, 465, 465)));
		
		//actions
		var deflect:Deflect = new Deflect();
		deflect.addDeflector(new WrappingBox(0, 0, 465, 465));
		
		var gravity:Gravity = new Gravity();
		field = new BitmapField();
		field.scaleX = field.scaleY = 2;
		field.massless = false;
		gravity.addField(field);
		
		addAction(deflect);
		addAction(gravity);
		addAction(new SpeedLimit(3));
		addAction(new Move());
	}
}